package com.accenture.adf.newcodington.module16.activity;


/**
 * Topic : Unit Testing
 * 
 * Description:
 * 
 * The Temperature class allows user to convert temperature from one unit to other
 */

public class TemperatureConvertor{

	// Attribute to display messages after conversion
	private String conversionMessage;


	// Default empty constructor
	public TemperatureConvertor() {

	}

	// Constructor accepts temperature object to initiate conversion
	
	public TemperatureConvertor(Temperature temperature)
			throws NullPointerException, ArithmeticException {
		try {
			// Check the object contents to see if a conversion is possible or
			// necessary.
			if (temperature == null)
				throw new NullPointerException("The Temperature Object was not found");
			if (temperature.getCurrUOM() == temperature.getNewUOM())
				throw new ArithmeticException("No conversion required.  The units of measure are the same.");

			// Catch the exception here
		} catch (NullPointerException ex) {
			System.out.println(ex.getMessage());
		} catch (ArithmeticException ex) {
			System.out.println(ex.getMessage());
			System.out.println("The temperature remains the same: "
					+ temperature.getTemperature() + " degrees "
					+ temperature.getCurrUOM());
		}

		// Display that a conversion will be was attempted
		conversionMessage = "Temperature Converter Initiated:  Temperature Data Received";
		System.out.println(conversionMessage);
	}

	/**
	 * Method to convert one unit into another

	 */
	public void convertTemperature(Temperature temperature)
			throws NullPointerException, ArithmeticException {
		conversionMessage = " Conversion Performed:  Old Temperature = "
				+ temperature.getTemperature() + " " + temperature.getCurrUOM()
				+ " ";

		// Determine which conversion will be performed
		switch (temperature.getCurrUOM()) {
		case 'K':
			if (temperature.getNewUOM() == 'C')
				convertKelvintoCelsius(temperature);
			else if (temperature.getNewUOM() == 'F')
				convertKelvintoFahrenheit(temperature);
			break;
		case 'C':
			if (temperature.getNewUOM() == 'K')
				convertCelsiusToKelvin(temperature);
			else if (temperature.getNewUOM() == 'F')
				convertCelsiusToFahrenheit(temperature);
			break;
		case 'F':
			if (temperature.getNewUOM() == 'K')
				convertFahrenheitToKelvin(temperature);
			else if (temperature.getNewUOM() == 'C')
				convertFahrenheitToCelsius(temperature);
			break;
		}

		// Check if the resulting temperature is below absolute zero. Must not
		// be lower than this.
		if (absoluteZeroCheck(temperature)) {
			String tempMessage; // Wait to append final temperature in case
								// temperature adjustment is needed
			tempMessage = " New Temperature = " + temperature.getTemperature()
					+ " " + temperature.getCurrUOM() + " ";
			System.out.println(conversionMessage + tempMessage);
			System.out
					.println("Temperature Below Absolute Zero! Must be reset to Absolute zero.");
			temperature.setTemperature(0);
			temperature.setCurrUOM('K');
			temperature.setNewUOM('K');
			conversionMessage += " New Temperature = "
					+ temperature.getTemperature() + " "
					+ temperature.getCurrUOM() + " ";
		} else {
			conversionMessage += " New Temperature = "
					+ temperature.getTemperature() + " "
					+ temperature.getCurrUOM() + " ";
		}
		System.out.println("Last Successful Action: " + conversionMessage);
	}

	//Method to convert Fahrenheit to Kelvin
	public void convertFahrenheitToKelvin(Temperature temperature)
			throws NullPointerException, ArithmeticException {
		float newTemperature;
		float currTemperature;
		currTemperature = temperature.getTemperature();
		newTemperature = (5f / 9f) * (currTemperature - 32f) + 273.15f;
		temperature.setTemperature(newTemperature);
		temperature.setCurrUOM('K');
		temperature.setNewUOM('F');
	}

	/**
	  Method to convert Fahrenheit to Celsius
	
	 */
	public void convertFahrenheitToCelsius(Temperature temperature)
			throws NullPointerException, ArithmeticException {
		float newTemperature;
		float currTemperature;
		currTemperature = temperature.getTemperature();
		newTemperature = (5f / 9f) * (currTemperature - 32f);
		temperature.setTemperature(newTemperature);
		temperature.setCurrUOM('C');
		temperature.setNewUOM('F');
	}

	/**
	 * Method to convert Celsius to Fahrenheit
	 * 
	 * @param temperature
	 * @throws NullPointerException
	 * @throws ArithmeticException
	 */
	public void convertCelsiusToFahrenheit(Temperature temperature)
			throws NullPointerException, ArithmeticException {
		float newTemperature;
		float currTemperature;
		currTemperature = temperature.getTemperature();
		newTemperature = ((9.0f / 5.0f) * currTemperature) + 32.0f;
		temperature.setTemperature(newTemperature);
		temperature.setCurrUOM('F');
		temperature.setNewUOM('C');
	}

	/**
	 * Method to convert Celsius to Kelvin
	 * 
	 * @param temperature
	 * @throws NullPointerException
	 * @throws ArithmeticException
	 */
	public void convertCelsiusToKelvin(Temperature temperature)
			throws NullPointerException, ArithmeticException {
		float newTemperature;
		float currTemperature;
		currTemperature = temperature.getTemperature();
		newTemperature = currTemperature + 273.15f;
		temperature.setTemperature(newTemperature);
		temperature.setCurrUOM('K');
		temperature.setNewUOM('C');
	}

	/**
	 * Method to convert Kelvin to Fahrenheit
	 * 
	 * @param temperature
	 * @throws NullPointerException
	 * @throws ArithmeticException
	 */
	public void convertKelvintoFahrenheit(Temperature temperature)
			throws NullPointerException, ArithmeticException {
		float newTemperature;
		float currTemperature;
		currTemperature = temperature.getTemperature();
		newTemperature = (9f / 5f) * (currTemperature - 273.15f) + 32f;
		temperature.setTemperature(newTemperature);
		temperature.setCurrUOM('F');
		temperature.setNewUOM('K');
	}

	/**
	 * Method to convert Kelvin to Celsius
	 * 
	 * @param temperature
	 * @throws NullPointerException
	 * @throws ArithmeticException
	 */
	public void convertKelvintoCelsius(Temperature temperature)
			throws NullPointerException, ArithmeticException {
		float newTemperature;
		float currTemperature;
		currTemperature = temperature.getTemperature();
		newTemperature = currTemperature - 273.15f;
		temperature.setTemperature(newTemperature);
		temperature.setCurrUOM('C');
		temperature.setNewUOM('K');
	}

	/**
	 * Method to check temperature for absolute zero
	 * 
	 * @param temperature
	 * @return boolean
	 * @throws NullPointerException
	 * @throws ArithmeticException
	 */
	public boolean absoluteZeroCheck(Temperature temperature)
			throws NullPointerException, ArithmeticException {
		float currTemperature = temperature.getTemperature();
		char currUOM = temperature.getCurrUOM();
		boolean checkResult = false;
		switch (currUOM) {
		case 'C':
			if (currTemperature < -273.15f)
				checkResult = true;
			break;
		case 'F':
			if (currTemperature < -459.67f)
				checkResult = true;
			break;
		case 'K':
			if (currTemperature < 0f)
				checkResult = true;
			break;
		}
		return checkResult;
	}
	// Getter and Setter methods
	public String getConversionMessage() {
		return conversionMessage;
	}

	public void setConversionMessage(String conversionMessage) {
		this.conversionMessage = conversionMessage;
	}

}
